﻿

#region USING
//
using System;
using System.Collections.Generic;
//using System.Linq;
//using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
//
#endregion USING


namespace Gsp315_AIBehaviors
{
    public enum agent_Type { ROCK=0, PAPER, SCISSOR, OBSTACLES, NEUTRAL };

    public class Agent
    {
        #region DATA_MEMBERS
        //
        #region PRIMARY_SETUP_OF_OBJECT (Minimal)
        //
        //PRIMARY SETUP of obj (Minimal)
        private Texture2D texture;          //D001: Texture of agent
        private Vector2 position;           //D002: Position of agent (Top-Left)
        private Vector2 size;               //D003: Size of agent (x-Width, y-Height)
        private Vector2 scale;              //D004: Scale of agent (1 = 100%)
        private Vector2 center;             //D005: Center of agent
        private bool isAlive;               //D006: Used to track dead agent AND decide IF agent should be Rendered
        //
        #endregion PRIMARY_SETUP_OF_OBJECT (Minimal)

        #region Movement_DIRECTION_N_ANGLE
        //
        //Movement DIRECTION / ANGLE of obj
        private float angleInRadians;       //Angle in Radians, direction object 'IS/SHOULD' move 
        private Vector2 direction;          //Normalized obj direction (theta/angle: converted into Vector)
        //
        #endregion Movement_DIRECTION_N_ANGLE

        #region CONTROL_ROTATION_MOVEMENT_SPEEDs
        //
        //Control: ROTATION SPEED
        private float rotation_Normal;      //Speed obj should rotate (in radians)
        private float rotation_Max;         //rotation speed: MAX Limit
        private float rotation_Min;         //rotation speed: MIN Limit

        //Control: MOVEMENT SPEED
        private float speed_Normal;         //Speed obj should be moving per frame
        private float speed_Max;            //obj speed: MAX Limit
        private float speed_Min;            //obj speed: MIN Limit
        //
        #endregion CONTROL_ROTATION_MOVEMENT_SPEEDs

        #region CONTROL_WANDER_BEHAVIOUR
        //
        private float wanderDistance;             //Magnitude from Agent->Center to wanderCircle->Center
        private float wanderRadius;               //Parameter Boundary (radius) for wonderTarget->Position
        private Vector2 wanderTarget_Direction; //Parameter for random calculation Wander Target Direction
        private Vector2 wanderTarget_Position;  //Parameter for Wander Target position
        private float wanderJitter;             //Max Random Displacement, applied to wanderTarget per second/frame (-1 <= n =< 1)
        //
        #endregion CONTROL_WANDER_BEHAVIOUR

        #region CONTROL_COLLISION_DETECTION
        //
        //Control: COLLISION DETECTION
        //private Texture2D collisionBoundary;
        private float collision_Radius;     //Radius to avoid obstacle collision, while wandering
        private float rayCast;              //Magnitude used to start Seek/Flee while wandering
        //
        #endregion CONTROL_COLLISION_DETECTION

        //Obj States: STEERING Behaviour(s)
        private GroupBehaviour behaviour;   //Behaviour obj should perform, Default-> Wander

        private float currentSpeed = 0.0f;  //Used to track current speed of agent
        private float counterWander = 0.0f; //Used to track time counter for obj direction update
        private float counterSeek = 0.0f;   //Used as counter when in Seek mode to pursue a target
        private float timer = 130.0f;       //Update obj direction of counter > timer
        private bool canFlee = false;       //Agent can decide whether to Escape, when in FLEE mode

        #region UI_DISPLAY_STATs
        //
        //Obj Identity, UI Display Stats
        private int index;                  //Unique identify for agent
        private agent_Type agentType;       //Identify which type of agent, Use this value: to implement Group behaviour, actions, etc...
        private int captureValue;           //Use this value to Decide if this agent is valued more to catch over another

        private int fleeValue;              //Points an agent get for fleeing this agent
        private int agentScore;             //Tally of an agent's Seek & Flee score
        //
        #endregion
        //
        #endregion DATA_MEMBERS


        
        #region OBJECT_CONSTRUCTION
        //
        //C001: DEFAULT CONSTRUCTOR
        public Agent(Texture2D texture)
        {
            Random xPosSeed = new Random((int)DateTime.Now.Ticks);
            Random yPosSeed = new Random((int)DateTime.Now.Millisecond);

            this.texture = texture;
            this.position = Helper.Position_Random(xPosSeed, yPosSeed, 50, 750, 50, 550);
            this.size = new Vector2(16.0f, 16.0f);
            
            init();
        }

        //C002: OVERLOADED CONSTRUCTOR
        public Agent(Texture2D texture, Vector2 position, Vector2 size)
        {
            this.texture = texture;
            this.position = position;
            this.size = size;

            init();
        }

        //C003: Init data members...
        private void init()
        {
            this.scale = new Vector2(1, 1);  //scale of obj
            isAlive = true;

            //Movement Direction/Angle of obj
            this.angleInRadians = Helper.AngleInRadians_Random();   //Random direction obj moves, in Radians
            this.direction = Helper.Radian2Vector(angleInRadians);  //Direction obj moves, Convert angleInRadians to Vector2
            direction.Normalize();                                  //Normalize direction to Unit Vector

            //Center is based on which direction obj is pointing
            this.center = this.position + Helper.Inverse(this.direction * (this.size / 2));    //origin used for rotation

            //Rotation Speed Controls
            this.rotation_Normal = 0.17f;   //Normal Rotating speed in radians (~10-degrees)
            this.rotation_Max = 0.26f;      //MAX Rotating speed in radians (~15-degrees)
            this.rotation_Min = 0.09f;      //MIN Rotating speed in radians (~5-degrees)

            //Movement Speed Controls
            this.speed_Normal = 0.80f;      //Normal Movement speed of obj
            this.speed_Max = 1.20f;         //MAX Movement speed of obj
            this.speed_Min = 0.45f;         //MIN Movement speed of obj

            //Wander Behaviour Controls
            this.wanderDistance = (int)this.size.X + 20;     //distance = 32
            this.wanderRadius = (int)this.size.X / 2;   //radius = size/2
            this.wanderTarget_Position = this.center;   //Set wanderTarget = agent->Center
            this.wanderTarget_Direction = new Vector2();//Set wanderTarget direction = <0,0>
            //this.wanderJitter = 20.0f;

            //Collision Detection helper data
            this.collision_Radius = 50.0f;
            this.rayCast = 100.0f;

            //Obj States: Steering Behaviour
            this.behaviour = new GroupBehaviour();
            this.behaviour.DefaultBehaviour = behaviour_Type.WANDER;
            this.behaviour.PrimaryBehaviour = behaviour_Type.SEEK;
            this.behaviour.SecondaryBehaviour = behaviour_Type.FLEE;

            //Obj Identity, UI Display Stats
            this.index = 0;
            this.agentType = agent_Type.NEUTRAL; //By default agent doesn't belong to a group
            this.captureValue = 1;
            this.fleeValue = 1;
            this.agentScore = 0;

            /************************************************************************
                        * [5/19/2011 Ronald]
                         * Will be updated by external SIM Controller Class, when arrays of
                         * agents will be created:
                         * 
                         * - Group behaviour
                         * - captureValue
                         * - index
                         * - fleeValue
                         * - agentScore
                         * - collisionRadius
                         * - rayCast
                         * 
                        ************************************************************************/
        }
        //
        #endregion OBJECT_CONSTRUCTION



        #region PROPERTIES
        //
        #region PRIMARY_SETUP_OF_OBJECT (Minimal)
        //
        public Texture2D Texture
        {
            get { return texture; }
            set { texture = value; }
        }
        //
        public Vector2 Position
        {
            get { return position; }
            set
            {
                this.position = value;
                this.position.X = (float)Math.Round(this.position.X, 2);
                this.position.Y = (float)Math.Round(this.position.Y, 2);

                //center = position + (size / 2);

                //Center is calculated based on INVERSED direction of obj 
                this.center = this.position + Helper.Inverse(this.direction * (this.size / 2));
                this.center.X = (float)Math.Round(this.center.X, 2);
                this.center.Y = (float)Math.Round(this.center.Y, 2);
            }
        }
        //
        public Vector2 Size
        {
            get { return size; }
            set { size = value; }
        }
        //
        public Vector2 Scale
        {
            get { return scale; }
            set { scale = value; }
        }
        //Origin used to rotate obj 
        public Vector2 Center
        {
            get { return center; }
            //set { center = value; }
        }
        //
        public bool IsAlive
        {
            get { return isAlive; }
            set { isAlive = value; }
        }
        //
        #endregion PRIMARY_SETUP_OF_OBJECT (Minimal)


        #region Movement_DIRECTION_N_ANGLE
        //
        //Tracks direction obj is moving in Radians
        //Input: angle in radians
        public float AngleInRadians
        {
            get { return this.angleInRadians; }
            set
            {
                //This ensures  rotation theta does not continue to grow and grow forever in +ve direction
                if (value > (float)Math.Round((float)Math.PI * 2, 2))
                {
                    this.angleInRadians = (float)Math.Round(value - Math.PI * 2, 2);
                }
                //This ensures  rotation theta does not continue to grow and grow forever in -ve direction
                if (value < (float)Math.Round((float)Math.PI * -2, 2))
                {
                    this.angleInRadians = (float)Math.Round(value + Math.PI * 2, 2);
                }
                else { this.angleInRadians = (float)Math.Round(value, 2); }

                //this.angleInRadians = value;
                this.direction = Helper.Radian2Vector(this.angleInRadians);
            }
        }
        //Direction obj is moving in Vector form
        public Vector2 Direction
        {
            get { return direction; }
            //set { direction = value; }
        }
        //
        #endregion Movement_DIRECTION_N_ANGLE


        #region CONTROL_ROTATION_MOVEMENT_SPEEDs
        //
        public float Rotation_Normal
        {
            get { return rotation_Normal; }
            set { rotation_Normal = value; }
        }
        //
        public float Rotation_Min
        {
            get { return rotation_Min; }
            set { rotation_Min = value; }
        }
        //
        public float Rotation_Max
        {
            get { return rotation_Max; }
            set { rotation_Max = value; }
        }
        //
        public float Speed_Normal
        {
            get { return speed_Normal; }
            set { speed_Normal = value; }
        }
        //
        public float Speed_Min
        {
            get { return speed_Min; }
            set { speed_Min = value; }
        }
        //
        public float Speed_Max
        {
            get { return speed_Max; }
            set { speed_Max = value; }
        }
        //
        #endregion CONTROL_ROTATION_MOVEMENT_SPEEDs


        #region CONTROL_WANDER_BEHAVIOUR
        //
        //Wander Distance
        public float WanderDistance
        {
            get { return wanderDistance; }
            set { this.wanderDistance = value; }
        }
        //Wander Distance
        public float WanderRadius
        {
            get { return wanderRadius; }
            set { this.wanderRadius = value; }
        }
        //
        //Wander Target Position
        public Vector2 WanderTarget_Position
        {
            get { return wanderTarget_Position; }
            set { this.wanderTarget_Position = value; }
        }
        //
        public float WanderTarget_Position_Y
        {
            get { return wanderTarget_Position.Y; }
            set { this.wanderTarget_Position.Y = value; }
        }
        //
        public float WanderTarget_Position_X
        {
            get { return wanderTarget_Position.X; }
            set { this.wanderTarget_Position.X = value; }
        }
        //Wander Target Position->NORMALIZED
        public void WanderTarget_Position_Normalize()
        {
            this.wanderTarget_Position.Normalize();
        }
        //
        //Wander Target Position
        public Vector2 WanderTarget_Direction
        {
            get { return wanderTarget_Direction; }
            set { this.wanderTarget_Direction = value; }
        }
        //
        public float WanderTarget_Direction_Y
        {
            get { return wanderTarget_Direction.Y; }
            set { this.wanderTarget_Direction.Y = value; }
        }
        //
        public float WanderTarget_Direction_X
        {
            get { return wanderTarget_Direction.X; }
            set { this.wanderTarget_Direction.X = value; }
        }
        //Wander Target Position->NORMALIZED
        public void WanderTarget_Direction_Normalize()
        {
            this.wanderTarget_Direction.Normalize();
        }
        //Wander Jitter
        public float WanderJitter
        {
            get { return wanderJitter; }
            set { this.wanderJitter = value; }
        }
        //
        #endregion CONTROL_WANDER_BEHAVIOUR


        #region CONTROL_COLLISION_DETECTION
        //
        public float Collision_Radius
        {
            get { return collision_Radius; }
            set { collision_Radius = value; }
        }
        //
        public float RayCast
        {
            get { return rayCast; }
            set { rayCast = value; }
        }
        //
        #endregion CONTROL_COLLISION_DETECTION


        #region UI_DISPLAY_STATs
        //
        public int Index
        {
            get { return index; }
            set { index = value; }
        }
        //
        public agent_Type AgentType
        {
            get { return agentType; }
            set { agentType = value; }
        }
        //
        public int CaptureValue
        {
            get { return captureValue; }
            set { captureValue = value; }
        }
        //
        public int FleeValue
        {
            get { return fleeValue; }
            set { fleeValue = value; }
        }
        //
        public int Score
        {
            get { return agentScore; }
            set { agentScore = value; }
        }
        //
        #endregion UI_DISPLAY_STATs
        //
        #endregion PROPERTIES



        #region GET-SET GROUP_BEHAVIOUR
        //
        public behaviour_Type DefaultBehaviour
        {
            get { return behaviour.DefaultBehaviour; }
            set { behaviour.DefaultBehaviour = value; }
        }
        //
        public behaviour_Type PrimaryBehaviour
        {
            get { return behaviour.PrimaryBehaviour; }
            set { behaviour.PrimaryBehaviour = value; }
        }
        //
        public behaviour_Type SecondaryBehaviour
        {
            get { return behaviour.SecondaryBehaviour; }
            set { behaviour.SecondaryBehaviour = value; }
        }
        //
        public GroupBehaviour getGroupBehaviour
        {
            get { return behaviour; }
        }
        //
        public void setGroupBehaviour(behaviour_Type defaultBehaviour, behaviour_Type primary, behaviour_Type secondary)
        {
            behaviour.DefaultBehaviour = defaultBehaviour;
            behaviour.PrimaryBehaviour = primary;
            behaviour.SecondaryBehaviour = secondary;
        }
        //
        #endregion GET-SET GROUP_BEHAVIOUR



        #region PRIVATE_METHODS
        //
        //Decide Steering Behaviour, called inside Update_Behaviour()
        private behaviour_Type DecideBehaviour(Agent agent)
        {
            behaviour_Type type = behaviour_Type.WANDER;

            //if challenging agent = ROCK
            if (agent.AgentType == agent_Type.ROCK)
            {
                switch ((int)this.agentType)
                {
                    //Agent 'ME' state either PAPER | SCISSOR
                    case (int)agent_Type.PAPER:
                        type = behaviour_Type.SEEK;
                        //agent.IsAlive = false;
                        break;
                    case (int)agent_Type.SCISSOR:
                        type = behaviour_Type.FLEE;
                        break;
                }
            }
            //if challenging agent = PAPER
            else if (agent.AgentType == agent_Type.PAPER)
            {
                //Agent 'ME' state either ROCK | SCISSOR
                switch ((int)this.agentType)
                {
                    case (int)agent_Type.ROCK:
                        type = behaviour_Type.FLEE;
                        break;
                    case (int)agent_Type.SCISSOR:
                        type = behaviour_Type.SEEK;
                        //agent.IsAlive = false;
                        break;
                }
            }
            //if challenging agent = SCISSOR
            else if (agent.AgentType == agent_Type.SCISSOR)
            {
                //Agent 'ME' state either ROCK | PAPER
                switch ((int)this.agentType)
                {
                    case (int)agent_Type.ROCK:
                        type = behaviour_Type.SEEK;
                        //agent.IsAlive = false;
                        break;
                    case (int)agent_Type.PAPER:
                        type = behaviour_Type.FLEE;
                        break;
                }
            }
            else { type = behaviour_Type.WANDER; }
            //
            return type;
        }

        //Update angleInRadians and direction if agent is colliding with window boundaries
        //Called inside Update_Behaviour()
        //TODO: FIX ME - Slow down UPDATE Times for agent movement
        private void BoundaryCheck(Vector2 moveDirection, GameTime gameTime)
        {
            Vector2 temp = this.position;

            //do boundary check...And wrap around the screen...
            float left = -this.size.X;  //-32.0f;
            float right = 800.0f;       //GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width;
            float top = -this.size.Y;   //-32.0f;
            float bottom = 600.0f;      //GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height;

            Vector2 timer = new Vector2((float)gameTime.ElapsedGameTime.TotalSeconds);

            //LEFT BOUND check....X-Position
            if (this.position.X < left)  //(left - this.size.X))
            {
                temp.X = right;
                Position = temp;
            }
            //RIGHT BOUND check....X-Position
            if (this.position.X > right)
            {
                temp.X = left;
                Position = temp;
            }
            //TOP BOUND check....Y-Position
            if (this.position.Y < top)
            {
                temp.Y = bottom;
                Position = temp;
            }
            //BOTTOM BOUND check....Y-Position
            if (this.position.Y > bottom)
            {
                temp.Y = top;
                Position = temp;
            }
            //STILL INSIDE SCREEN....continue on its path...
            ////else
            ////{
            Position += moveDirection; //this.position += moveDirection;
            ////}
        }

        //Update Score, called inside Update_Behaviour()
        //TODO: FIX ME: Logic for Captured | Escaped....
        private void UpdateScore_FleeOrSeek(Agent target, float magtitude_This_Target)
        {
            if (this.behaviour.DefaultBehaviour == behaviour_Type.FLEE)
            {
                //Agent 'ME' got captured...
                if (this.collision_Radius / 2 <= magtitude_This_Target)
                {
                    this.agentScore -= target.captureValue;
                    //this.isAlive = false;
                }
            }
            else if (this.behaviour.DefaultBehaviour == behaviour_Type.SEEK)
            {
                //Agent 'ME' captured target...
                if (magtitude_This_Target <= target.collision_Radius / 2)
                {
                    this.agentScore += target.FleeValue;
                }
            }
        }
        //
        #endregion PRIVATE_METHODS



        #region PUBLIC_METHODS
        //
        //Use the gameWorld asset list to track down who to seek, flee or continue wandering....
        public void Update_Behaviour(ref List<Agent> agents, GameTime gameTime)
        {
            
            Vector2 temp = new Vector2();
            //float speed = 0.0f;

            foreach (Agent agent in agents)
            {
                //Check: IF self, keep WANDERing
                if (this == agent)
                {
                    this.DefaultBehaviour = behaviour_Type.WANDER; 
                    AngleInRadians += SteeringBehaviours.Wander(this);

                    currentSpeed = this.speed_Normal;
                }
                else
                {
                    float mag, x, y;
                    x = this.center.X - agent.center.X; //position.X - agent.position.X;
                    y = this.center.Y - agent.center.Y; //position.Y - agent.Position.Y;

                    mag = (float)Math.Sqrt((x * x) + (y * y));

                    //NEXT ITERATION: Priority to FLEE over SEEK...
                    if ((mag <= this.collision_Radius + agent.Collision_Radius))
                    {
                        this.behaviour.DefaultBehaviour = DecideBehaviour(agent);

                        switch ((int)this.behaviour.DefaultBehaviour)
                        {
                            case (int)behaviour_Type.FLEE:
                                AngleInRadians = SteeringBehaviours.Flee(this, agent);
                                //CAPTURED....
                                float captureDistance = (float)Math.Sqrt(Math.Pow((agent.position.X - this.position.X), 2) + Math.Pow((agent.position.Y - this.position.Y), 2));

                                //Decide Whether 'YES | NO" -> Escape
                                if (captureDistance <= this.size.X + agent.size.X)
                                {
                                    //Check for One Time Offer to Escape
                                    if (!canFlee)
                                    {
                                        Random rand = new Random();

                                        if (rand.NextDouble() >= 0.5) { canFlee = true; }

                                        //Decided to Escape
                                        if (canFlee)
                                        {
                                            currentSpeed += this.speed_Max;
                                            AngleInRadians += this.rotation_Max * 2;
                                        }
                                        //Will get captured
                                        else 
                                        { 
                                            currentSpeed = this.speed_Normal;
                                            AngleInRadians = SteeringBehaviours.Wander(this);
                                        }
                                    }
                                }
                                
                                if (captureDistance <= (this.size.X)) //+ agent.size.X / 2))
                                {
                                    canFlee = false;
                                    this.isAlive = false;
                                }

                                //currentSpeed = this.speed_Normal;
                                break;
                            //
                            case (int)behaviour_Type.SEEK:
                                AngleInRadians = SteeringBehaviours.Seek(this, agent);
                                //this.position += Vector2.Multiply(this.direction, speed_Min);
                                currentSpeed = this.speed_Max;
                                break;
                          }//switch
                    }
                    else
                    {
                        this.DefaultBehaviour = behaviour_Type.WANDER;

                        counterWander += (float)gameTime.ElapsedGameTime.TotalMilliseconds;

                        if (counterWander > timer)
                        {
                            AngleInRadians += SteeringBehaviours.Wander(agent);
                            currentSpeed = this.speed_Normal;
                            //AngleInRadians += SteeringBehaviours.WanderJitter(this);
                            counterWander = 0.0f;
                        }
                         //2.0f;
                    }
                }
                //
                //NEXT ITERATION: if (this.rayCast....), Use rayCast to make some decisions...or Seek
            }//foreach

            //
            //NEXT ITERATION: if (this.rayCast....), Use rayCast to make some decisions...or Seek

            //update position
            temp.X = (float)Math.Round(this.direction.X * currentSpeed, 2);
            temp.Y = (float)Math.Round(this.direction.Y * currentSpeed, 2);
            //
            //this.position += temp;
            //if ( (int)gameTime.ElapsedGameTime.TotalSeconds % 20 == 0)
            //{
            BoundaryCheck(temp, gameTime);
            //}
        }

        
        //
        public void Draw(SpriteBatch spriteBatch)
        {
            //origin = origin of rotation
            //In XNA, origin (0,0) is obj.Position...
            Vector2 origin = new Vector2(size.X / 2, size.Y / 2);
            spriteBatch.Draw(this.texture, this.position, null, Color.White, this.angleInRadians + (float)Math.Round(Math.PI / 2, 2), origin, scale.X, SpriteEffects.None, 0f);
        }
        //
        #endregion PUBLIC_METHODS


    }//class
}//namespace




#region PREV_CODE
////namespace Gsp315_AIBehaviors
////{
////    public struct Steering
////    {
////        public Vector2 linear;
////        public float angular;

////        public void SteeringOutput()
////        {
////            linear = Vector2.Zero;
////            angular = 0.0f;
////        }
////    }

    
////    //
////    public class Player
////    {

////        #region DATA MEMBERS

////        private Texture2D texture;
////        private Vector2 position;
////        private Vector2 size;
////        private Vector2 scale;
////        private Vector2 center;
        
////        private float rotation_Speed;
////        public Steering steering;

////        private float maxAcceleration = 1.0f;

////        #endregion DATA MEMBERS



////        #region OBJECT CONSTRUCTION

////        public Player(Texture2D newTexture)
////        {
////            texture = newTexture;
////            position = new Vector2(0, 0);
////            size = new Vector2(32.0f, 32.0f);
////            scale = new Vector2(1, 1);
////            rotation = 0.0f;
////            center = position + (size / 2);
////        }// end Constructor()

////        public Player(Texture2D newTexture, Vector2 position, Vector2 size)
////        {
////            texture = newTexture;
////            this.position = position;
////            this.size = size;
////            rotation = 0.0f;
////            center = position + (size / 2);
////            scale = new Vector2(1, 1);//new Vector2((BBGlobalConfig.getWindowWidth() / size.X), (BBGlobalConfig.getWindowHeight() / size.Y));
////        }// end Overloaded Constructor 2()

////        #endregion OBJECT CONSTRUCTION



////        #region PROPERTIES

////        public Texture2D Texture
////        {
////            get{ return texture; }
////            set{ texture = value; }
////        }

////        public Vector2 Position
////        {
////            get{ return position; }
////            set{ position = value; }
////        }

////        public Vector2 Center
////        {
////            get { return center; }
////            set { center = value; }
////        }

////        public Vector2 Size
////        {
////            get { return size; }
////            set { size = value; }
////        }

////        #endregion PROPERTIES



////        #region PUBLIC METHODS

////        public void rotateToward(Enemy enemy)
////        {
////            //float XDistance = (enemy.Position.X + (enemy.Size.X / 2)) - (this.position.X + (this.size.X / 2));
////            //float YDistance = (enemy.Position.Y + (enemy.Size.Y / 2) - (this.position.Y + (this.size.Y / 2)));

////            float XDistance = (this.position.X + (this.size.X / 2)) - (enemy.Position.X + (enemy.Size.X / 2));
////            float YDistance = (this.position.Y + (this.size.Y / 2)) - (enemy.Position.Y + (enemy.Size.Y / 2));

////            rotation = (float)Math.Atan2(YDistance, XDistance) + 30;
////            //rotation += .1f;//randomNumber.Next(1, 360);
////        }

////        public void Seek(Enemy enemy)
////        {
////            steering = new Steering();

////            steering.linear = (enemy.Position - this.position);

////            steering.linear.Normalize();
////            steering.linear *= maxAcceleration;

////            steering.angular = 0.0f;
////            position += steering.linear;

////            rotateToward(enemy);
////            //return steering;
////        }

////        public bool Collides(Enemy enemy)
////        {
////            if ((this.position.X >= enemy.Position.X) && (this.position.X <= (enemy.Position.X + enemy.Size.X)) &&
////               ((this.position.Y <= enemy.Position.Y) && (this.position.Y <= (enemy.Position.Y + enemy.Size.Y))))
////            {
////                return true;
////            }
////            else
////            {
////                return false;
////            }
////        }

////        public void Draw(SpriteBatch spriteBatch)
////        {
////            int xPos = (int)position.X;
////            int yPos = (int)position.Y;
////            center = new Vector2((size.X / 2), ((size.Y / 2) + 4));

////            spriteBatch.Draw(texture, new Vector2(xPos + center.X, yPos + center.Y), null, Color.White, rotation, center, scale, SpriteEffects.None, 0f);
////        }// end Draw() 

////        #endregion PUBLIC METHODS     


////    }
////}
#endregion PREV_CODE
